/**
 * @公司:公约树
 * @位置:苏州
 * @Classname AnimeViewUtil
 * @Date 2022-06-04 上午 07:00
 * @Created by hanWanLu
 * @auther 中文:韩万路
 */


package com.animeJava;

import com.animeJava.core.AnimeJava;
import com.animeJava.core.EasingData;
import com.animeJava.dao.animeEvent.AnimeRender;
import com.animeJava.enumData.PatternEnum;
import com.animeJava.mode.PositionVarModel;
import com.animeJava.mode.animeModel.AnimeProperty;
import com.animeJava.util.WindowFocusUtil;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleListProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Effect;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.*;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.Window;
import javafx.util.StringConverter;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

import static com.animeJava.enumData.PatternEnum.values;

/**
 * 动画视图贝塞尔编辑器
 */
public class AnimeViewUtil extends Application  {

    private double moveX = 0 ;
    private double moveY = 0;
    private double stageMoveX = 0 ;
    private double stageMoveY = 0;
    private Popup  menu = new Popup();
    private Stage  stage;
    int cotent = 3;
    private CubicCurve cubicCurve;
    private CanvasEventBean canvasEventBean;
    private TextField input;
    private AnimeNodeView animeNodeView;

    public static void main(String[] args) {
        launch(args);
    }
    @Override
    public void start(Stage stage) throws Exception {
        this.stage = stage;
        popupInit();
        stage.initStyle(StageStyle.TRANSPARENT);

        AnchorPane main = new AnchorPane();
        Scene scene = new Scene(main);
        stage.setScene(scene);
        scene.setFill(null);
        main.setStyle("-fx-background-color: #0000");
        setSize(main ,"width",600);
        setSize(main ,"height",450);

        AnchorPane root = new AnchorPane();
        main.getChildren().add(root);
        AnchorPane.setTopAnchor(root , 10D);
        AnchorPane.setRightAnchor(root , 10D);
        AnchorPane.setLeftAnchor(root , 10D);
        AnchorPane.setBottomAnchor(root , 10D);
        root.setStyle("-fx-background-color: #18181f ; -fx-background-radius: 15px ; -fx-border-color: #504c4c ; -fx-border-radius: 15px");
        root.setEffect(newBorderBlur());

        //************创建头部栏
        HBox headerPane = new HBox();
        root.getChildren().add(headerPane);
        AnchorPane.setTopAnchor(headerPane , 5D);
        AnchorPane.setRightAnchor(headerPane , 5D);
        AnchorPane.setLeftAnchor(headerPane , 5D);
        setSize(headerPane ,"height",30);
        headerPane.setCursor(Cursor.MOVE);
        headerPane.setAlignment(Pos.CENTER_RIGHT);
        Background background = new Background(new BackgroundFill( new Color(1, 1, 1, 0.1),null,null));
        headerPane.setBackground(background);
        headerPane.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                moveX =event.getScreenX();
                moveY =event.getScreenY();
                stageMoveX = stage.getX();
                stageMoveY = stage.getY();

            }
        });
        headerPane.setOnMouseDragged(event->{
            //计算
            stage.setX(stageMoveX + event.getScreenX() - moveX);
            stage.setY(stageMoveY + event.getScreenY() - moveY);

        });
        headerPane.setOnMouseReleased(value->{
        });

        //************创建title
        Label titleText = new Label("动画曲线IDE v2.1");
        headerPane.getChildren().add(titleText);
        titleText.setTextFill(Paint.valueOf("#cce"));
        headerPane.setMargin(titleText , new Insets(0,0,0,5));

        //************创建模式切换
        ComboBox<PatternEnum> modelCheck = new ComboBox<>();
        modelCheck.setMinWidth(70);
        ObservableList<PatternEnum> modelCheckArray = FXCollections.observableArrayList(PatternEnum.values());
        modelCheck.setItems(modelCheckArray);
        modelCheck.converterProperty().set(new StringConverter<PatternEnum>() {
            @Override
            public String toString(PatternEnum object) {
                return object.getName();
            }
            @Override
            public PatternEnum fromString(String string) {
                return null;
            }

        });
        modelCheck.selectionModelProperty().addListener(new ChangeListener<SingleSelectionModel<PatternEnum>>() {
            @Override
            public void changed(ObservableValue<? extends SingleSelectionModel<PatternEnum>> observable, SingleSelectionModel<PatternEnum> oldValue, SingleSelectionModel<PatternEnum> newValue) {
                switch (newValue.getSelectedItem()){
                    case BOUNCE:

                        break;
                    default:


                }
            }
        });
        modelCheck.getSelectionModel().select(0);
        headerPane.getChildren().add(modelCheck);

        HBox hBox1 = new HBox();
        headerPane.getChildren().add(hBox1);
        HBox.setHgrow( hBox1,Priority.ALWAYS);
        //************创建按钮
        Button close = (Button) newHeaderButton("关闭");
        headerPane.getChildren().add(close);
        headerPane.setMargin(close , new Insets(0,5,0,0));
        close.setStyle("-fx-background-color: rgba(255,255,255,0.29) ; -fx-background-radius: 8px");
        close.intersects(0,0,0,0);
        headerPane.setCursor(Cursor.HAND);
        setSize(close ,"width",60);
        close.setOnAction(value->{
            stage.hide();
            AnimeJava.close();
        });

        //头部栏的动画创建
        AnimeProperty animeProperty = new AnimeProperty();
        animeProperty.addKeyFrames(0,0.1D);
        animeProperty.addKeyFrames(100,0.2D);
        animeProperty.setDuration(200);
        final boolean[] animeFlag = {false};
        AnimeJava animeJava = new AnimeJava(animeProperty);

        animeJava.update(new AnimeRender() {
            @Override
            public boolean run(Double timeTo, Map<String, PositionVarModel> animeInfo, List<Double> data) {
                if(data.get(0) != null){
                    headerPane.setBackground( new Background(new BackgroundFill( new Color(1, 1, 1, data.get(0)),new CornerRadii(10),null)));
                }
                if(headerPane.getScene() != null){
                    animeFlag[0] = true;
                }
                if(animeFlag[0]){
                    return headerPane.getScene() != null;
                }
                return true;
            }
        });
        headerPane.setOnMouseExited(event -> animeJava.playFlashback());
        headerPane.setOnMouseEntered(event -> animeJava.play());


        //*************动画控制画布
        VBox hBox = new VBox();
        root.getChildren().add(hBox);
        AnchorPane.setTopAnchor(hBox,100D);
        AnchorPane.setRightAnchor(hBox,0D);
        AnchorPane.setLeftAnchor(hBox,0D);
        hBox.setAlignment(Pos.CENTER);

        //创建画布内容
        AnchorPane canvas = createCanvas(250);
        hBox.getChildren().add(canvas);
        AnimeProperty canvasAnimeProperty = new AnimeProperty();
        canvasAnimeProperty.addKeyFrames(0,0.09D);
        canvasAnimeProperty.addKeyFrames(100,0.2);
        canvasAnimeProperty.setDuration(200);
        final boolean[] animeFlag1 = {false};
        AnimeJava canvasAnimeJava = new AnimeJava(canvasAnimeProperty);
        canvasAnimeJava.update(new AnimeRender() {
            @Override
            public boolean run(Double timeTo, Map<String, PositionVarModel> animeInfo, List<Double> data) {
                if(data.get(0) != null) canvas.setBackground( new Background(new BackgroundFill( new Color(1, 1, 1, data.get(0)),new CornerRadii(10),null)));

                if(canvas.getScene() != null){
                    animeFlag1[0] = true;
                }
                if(animeFlag1[0]){
                    return canvas.getScene() != null;
                }
                return true;
            }
        });
        canvas.setOnMouseExited(event -> canvasAnimeJava.playFlashback());
        canvas.setOnMouseEntered(event -> canvasAnimeJava.play());


        //创建lineCanvas
        AnchorPane lineCanvas = new AnchorPane();
        canvas.getChildren().add(lineCanvas);
        AnchorPane.setTopAnchor(lineCanvas,0D);
        AnchorPane.setRightAnchor(lineCanvas,0D);
        AnchorPane.setBottomAnchor(lineCanvas,0D);
        AnchorPane.setLeftAnchor(lineCanvas,0D);
        lineCanvas.setScaleY(-1);
//        lineCanvas.scale

        //创建节点的画布
        AnchorPane nodeCanvas = new AnchorPane();
        canvas.getChildren().add(nodeCanvas);
        AnchorPane.setTopAnchor(nodeCanvas,0D);
        AnchorPane.setRightAnchor(nodeCanvas,0D);
        AnchorPane.setBottomAnchor(nodeCanvas,0D);
        AnchorPane.setLeftAnchor(nodeCanvas,0D);
        nodeCanvas.setScaleY(-1);

        //


        //画布添加贝塞尔曲线
        cubicCurve = new CubicCurve();
        lineCanvas.getChildren().add(cubicCurve);
        cubicCurve.setStartX(0);
        cubicCurve.setStartY(0);
        cubicCurve.setFill(null);
        cubicCurve.setStroke(Paint.valueOf("#aaf"));
        cubicCurve.setStrokeWidth(2);
        cubicCurve.setEndX(250);
        cubicCurve.setEndY(250);
        canvasEventBean = new CanvasEventBean();
        cubicCurve.controlX1Property().addListener((observable, oldValue, newValue) -> {
            canvasEventBean.execute(
                    cubicCurve.getControlX1(),
                    cubicCurve.getControlY1(),
                    cubicCurve.getControlX2(),
                    cubicCurve.getControlY2());
        });
        cubicCurve.controlY1Property().addListener((observable, oldValue, newValue) -> {
            canvasEventBean.execute(
                    cubicCurve.getControlX1(),
                    cubicCurve.getControlY1(),
                    cubicCurve.getControlX2(),
                    cubicCurve.getControlY2());
        });
        cubicCurve.controlX2Property().addListener((observable, oldValue, newValue) -> {
            canvasEventBean.execute(
                    cubicCurve.getControlX1(),
                    cubicCurve.getControlY1(),
                    cubicCurve.getControlX2(),
                    cubicCurve.getControlY2());
        });
        cubicCurve.controlY2Property().addListener((observable, oldValue, newValue) -> {
            canvasEventBean.execute(
                    cubicCurve.getControlX1(),
                    cubicCurve.getControlY1(),
                    cubicCurve.getControlX2(),
                    cubicCurve.getControlY2());
        });



        //检测节点
        nodeCanvas.getChildren().addListener(new ListChangeListener<Node>() {
            @Override
            public void onChanged(Change<? extends Node> c) {
                ObservableList<? extends Node> list = c.getList();
                //创建节点大于1则创建画布上的线段
                if(list.size() >= 2){
                    Map<String, Node> nodes = new HashMap<>();
                    for (Node item:list) {
                        nodes.put(item.getId() , item);
                    }
                    //清空node line的线段
                    Iterator<Node> iterator = lineCanvas.getChildren().iterator();
                    while (iterator.hasNext()){
                        Node next = iterator.next();
                        if ("line".equals(next.getId())){
                            iterator.remove();
                        }
                    }
                    //给每一个node添加内容
                    for (int i = 0; i < nodes.size()-1; i++) {
                        Node nodeItemIn = nodes.get(i + "");
                        Node nodeItemTo = nodes.get((i+1) + "") == null ?nodes.get("N"):nodes.get((i+1) + "");

                        double inLayoutX = nodeItemIn.getLayoutX();
                        double inLayoutY = nodeItemIn.getLayoutY();
                        double toLayoutX = nodeItemTo.getLayoutX();
                        double toLayoutY = nodeItemTo.getLayoutY();
                        //创建点链接线
                        Line line = new Line();
                        line.setStroke(Paint.valueOf("#aaf4"));
                        line.setStrokeWidth(2);
                        line.setId("line");
                        line.setStartX(inLayoutX);
                        line.setStartY(inLayoutY);

                        line.setEndX(toLayoutX);
                        line.setEndY(toLayoutY);

                        nodeItemIn.layoutXProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                line.setStartX(observable.getValue().doubleValue());
                            }
                        });

                        nodeItemIn.layoutYProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                line.setStartY(observable.getValue().doubleValue());
                            }
                        });


                        nodeItemTo.layoutXProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                 line.setEndX(observable.getValue().doubleValue());
                            }
                        });


                        nodeItemTo.layoutYProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                line.setEndY(observable.getValue().doubleValue());
                            }
                        });



                        lineCanvas.getChildren().add(line);
                    }
                }
            }
        });
        //右击添加节点操作
        canvas.setOnMousePressed(mouseEvent ->{
            if(mouseEvent.getButton() == MouseButton.SECONDARY){
                Pane pane = menuShow(stage, mouseEvent.getScreenX(), mouseEvent.getScreenY());
                double y = mouseEvent.getY();
                double x = mouseEvent.getX();
                System.out.println("x:"+x +"  y:"+y);
                Button add = addMenuButton(pane,"添加节点");
                add.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                        System.out.println("添加节点 相对位置:x-"+x+"   y-"+y);
                        double relativelX = x;
                        double relativelY = y ;


                        AnchorPane controllPointerBSREnd = createControllPointerBSR(relativelX, relativelY, Color.valueOf("#5BB3CEFF"), cotent+"", null);
                        controllPointerBSREnd.layoutXProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                Number value = observable.getValue();
//                                cubicCurve.setControlX2((Double) value);

                                canvasEventBean.execute(
                                        cubicCurve.getControlX1(),
                                        cubicCurve.getControlY1(),
                                        controllPointerBSREnd.getLayoutX(),
                                        controllPointerBSREnd.getLayoutY(),
                                        cubicCurve.getControlX2(),
                                        cubicCurve.getControlY2());
                            }
                        });
                        controllPointerBSREnd.layoutYProperty().addListener(new ChangeListener<Number>() {
                            @Override
                            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                                Number value = observable.getValue();
//                                cubicCurve.setControlY2((Double) value);
                                canvasEventBean.execute(
                                        cubicCurve.getControlX1(),
                                        cubicCurve.getControlY1(),
                                        controllPointerBSREnd.getLayoutX(),
                                        controllPointerBSREnd.getLayoutY(),
                                        cubicCurve.getControlX2(),
                                        cubicCurve.getControlY2());
                            }
                        });

                        controllPointerBSREnd.setLayoutX(controllPointerBSREnd.getLayoutX()+0.00001);
                        controllPointerBSREnd.setLayoutY(controllPointerBSREnd.getLayoutY()+0.00001);

                        cotent++;
                        nodeCanvas.getChildren().add(controllPointerBSREnd);
//                        controllPointerBSREnd.
                    }
                });
                //判断当前是否是在节点上
                if(mouseEvent.getTarget() instanceof AnchorPane){
                    AnchorPane targetI = (AnchorPane) mouseEvent.getTarget();
                    if (targetI.getId() != null){

                        Button remove = addMenuButton(pane,"删除当前节点");
                        remove.setOnAction(new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event) {
                                canvas.getChildren().remove(targetI);
                            }
                        });
                    }
                }

            }

        });
        WindowFocusUtil windowFocusUtil = new WindowFocusUtil(menu, canvas);
        windowFocusUtil.setWindowFocusEvent(new WindowFocusUtil.WindowFocusEvent() {
            @Override
            public void run(String msg) {
                menuHide();
            }
        });

        //画布添加节点基本节点的添加
        nodeCanvas.getChildren().add(createControllPointerBSR(0,0,Color.valueOf("#33C6E0D1"),"0" , null));
        nodeCanvas.getChildren().add(createControllPointerBSR(250,250,Color.valueOf("#33C6E0D1"),"N" , null));

        //创建基础控制节点
        AnchorPane controllPointerBSR = createControllPointerBSR(0, 240, Color.valueOf("#5BB3CEFF"), 1 + "", null);
        controllPointerBSR.layoutXProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                cubicCurve.setControlX1(observable.getValue().doubleValue());
            }
        });
        controllPointerBSR.layoutYProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                cubicCurve.setControlY1(observable.getValue().doubleValue());
            }
        });

        controllPointerBSR.setLayoutX(controllPointerBSR.getLayoutX()+0.00001);
        controllPointerBSR.setLayoutY(controllPointerBSR.getLayoutY()+0.00001);

        nodeCanvas.getChildren().add(controllPointerBSR);
        AnchorPane controllPointerBSR1 = createControllPointerBSR(240, 0, Color.valueOf("#5BB3CEFF"), 2 + "", null);

        controllPointerBSR1.layoutXProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                cubicCurve.setControlX2(observable.getValue().doubleValue());
            }
        });
        controllPointerBSR1.layoutYProperty().addListener(new ChangeListener<Number>() {
            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                cubicCurve.setControlY2(observable.getValue().doubleValue());
            }
        });

        controllPointerBSR1.setLayoutX(controllPointerBSR1.getLayoutX()+0.00001);
        controllPointerBSR1.setLayoutY(controllPointerBSR1.getLayoutY()+0.00001);

        nodeCanvas.getChildren().add(controllPointerBSR1);
        //添加控制基础节点


        //添加底部控制显示节点
        VBox vBox = new VBox();
        root.getChildren().add(vBox);
        AnchorPane.setRightAnchor(vBox , 0D);
        AnchorPane.setBottomAnchor(vBox , 0D);
        AnchorPane.setLeftAnchor(vBox , 0D);
        vBox.setMinHeight(60);
        vBox.setAlignment(Pos.TOP_CENTER);

        input = createInput("0.82,0.20,0.18,0.97");
        vBox.setMargin(input,new Insets(0,0,4,0));
        vBox.getChildren().add(input);

        animeNodeView = new AnimeNodeView();
        vBox.getChildren().add( animeNodeView.getNode());


        EventHandler<KeyEvent> eventHandler = new EventHandler<KeyEvent>() {
            @Override
            public void handle(KeyEvent event) {
                if (event.getCode() == KeyCode.ENTER) {
                    scene.getRoot().setFocusTraversable(true);
                    String text = input.getText();
                    String[] split = text.split(",");
                    if (split.length % 2 == 0 && split.length >= 4) {
                        //插入节点位置
                        Map<String, Node> nodes = new HashMap<>();
                        for (Node item : nodeCanvas.getChildren()) {
                            nodes.put(item.getId(), item);
                        }
                        ArrayList<Double> doubles = new ArrayList<>();

                        for (int i = 0; i < nodes.size() - 2; i++) {
                            Node node = nodes.get((i + 1) + "");
                            double x = new Double(split[i * 2 + 0]);
                            double y = new Double(split[i * 2 + 1]);
                            node.setLayoutX(x * 250);
                            node.setLayoutY(y * 250);
                            doubles.add(x);
                            doubles.add(y);
                        }

                        //播放动画
                        Double[] d = new Double[doubles.size()];
                        doubles.toArray(d);
                        animeNodeView.play(d);

                    } else {
                        //获取point的节点并插入到input中去
                        canvasEventBean.execute(
                                cubicCurve.getControlX1(),
                                cubicCurve.getControlY1(),
                                cubicCurve.getControlX2(),
                                cubicCurve.getControlY2());

                    }
                    System.out.println(input.getText());


                }
            }
        };

        canvasEventBean.addEvent(new CanvasEvent() {
            @Override
            public void event(String data) {
                input.setText(data);
            }
        });

        input.setOnKeyPressed(eventHandler);

        KeyEvent keyEvent = new KeyEvent(null,null,KeyEvent.KEY_PRESSED,null,null,KeyCode.ENTER,false,false,false,false);
        eventHandler.handle(keyEvent);
//        canvasEventBean.execute(
//                cubicCurve.getControlX1(),
//                cubicCurve.getControlY1(),
//                cubicCurve.getControlX2(),
//                cubicCurve.getControlY2());

        initOver();
        stage.show();
    }

    //加载完毕后执行
    private void initOver(){

    }


    private void setSize(Region node , String prperty , int size){
        if (prperty.equals("width")){
            node.setPrefWidth(size);
            node.setMinWidth(size);
            node.setMaxWidth(size);
        }else if(prperty.equals("height")){
            node.setPrefHeight(size);
            node.setMinHeight(size);
            node.setMaxHeight(size);
        }
    }

    private Effect newBorderBlur(){
        DropShadow shadow = new DropShadow();
        shadow.setHeight(20);
        shadow.setWidth(20);
        shadow.setColor(Color.BLACK);
        return shadow;
    }

    private Node newHeaderButton(String text){
        Button button = new Button(text);
        button.setStyle("-fx-background-color: #0000;-fx-border-color:#0000;");
        setSize(button , "heiht",10);
        setSize(button , "width",10);

        return button;
    }

    private AnchorPane createCanvas(int size){
        AnchorPane anchorPane = new AnchorPane();
        setSize(anchorPane,"width",size);
        setSize(anchorPane,"height",size);
        anchorPane.setStyle("-fx-background-color: rgba(255,255,255,0.09);-fx-background-radius: 10px");
        return anchorPane;
    }

    /**
     * 创建贝塞尔控制点
     * @return
     */
    private AnchorPane createControllPointerBSR(double relativelX, double relativelY,Color color , String id ,Position moveData ){
        //        创建id
        AnchorPane button = new AnchorPane();
        button.setId(id);
        setSize(button  ,"width", 20);
        setSize(button, "height" , 20);
//        AnchorPane.setBottomAnchor(button,-10D);
//        AnchorPane.setLeftAnchor(button,-10D);
        button.setStyle("-fx-background-radius: 20px; -fx-background-color: #8888; -fx-border-color: #0000");
        button.setCursor(Cursor.MOVE);
        button.setLayoutX(relativelX);
        button.setLayoutY(relativelY);

        ObservableList<Transform> transforms = button.getTransforms();
        Translate translate = new Translate(-10, -10);
        transforms.add(translate);


        Button buttonInner = new Button();
        button.getChildren().add(buttonInner);
        AnchorPane.setTopAnchor(buttonInner,3D);
        AnchorPane.setRightAnchor(buttonInner,3D);
        AnchorPane.setBottomAnchor(buttonInner,3D);
        AnchorPane.setLeftAnchor(buttonInner,3D);
        BackgroundFill backgroundFill = new BackgroundFill(color, new CornerRadii(20), null);
        buttonInner.setBackground(new Background(backgroundFill));
        if( moveData!= null){
            moveData.run(button );
        }
        //是否可以移动
        if(id != null && !"0".equals(id) && !"N".equals(id) ){
            //当前按下的位置
            double[] moveX = {0};
            double[] moveY = {0};
            //当前节点的位置
            final double[] nodeX = {0};
            final double[] nodeY = {0};
            buttonInner.setOnMousePressed(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    moveX[0] =event.getScreenX();
                    moveY[0] =event.getScreenY();
                    nodeX[0] = button.getLayoutX();
                    nodeY[0] = button.getLayoutY() ;
                }
            });
            buttonInner.setOnMouseDragged(event->{
                //计算
                double v = nodeX[0] + event.getScreenX() - moveX[0];
                button.setLayoutX(v >= 0 && v <= 250?v:button.getLayoutX());
                button.setLayoutY((255) - (255 - nodeY[0] + event.getScreenY() - moveY[0]));
                if(moveData != null){
                    moveData.run(button  );
                }


            });
            buttonInner.setOnMouseEntered(event -> {

            });
        }

        buttonInner.setOnMouseReleased(event -> {
            String text = input.getText();
            String[] split = text.split(",");
            if(split.length%2 == 0 && split.length >= 4){
                //插入节点位置
                ArrayList<Double> doubles = new ArrayList<>();

                for (int i = 0; i < split.length/2; i++) {
                    double x = new Double(split[i * 2 + 0]) ;
                    double y = new Double(split[i * 2 + 1]) ;
                    doubles.add(x);
                    doubles.add(y);
                }

                //播放动画
                Double[] d = new Double[doubles.size()];
                doubles.toArray(d);
                animeNodeView.play(d);
            }
        });
        return button;
    }

    /**
     * 创建输入贝塞尔曲线码
     * @return
     */
    private TextField createInput(String str){
        TextField textField = new TextField(str);

        textField.setMinWidth(250);
        textField.setMaxWidth(250);
        textField.setMinHeight(24);
        textField.setAlignment(Pos.CENTER);
        textField.setPadding( new Insets(0));
        BackgroundFill backgroundFill = new BackgroundFill(Paint.valueOf("#fff5"),new CornerRadii(10),new Insets(0));
        Background background = new Background(backgroundFill);
        textField.setBackground(background);
        Border border = new Border(new BorderStroke(Paint.valueOf("#aaf6"),
                new BorderStrokeStyle(
                        StrokeType.OUTSIDE, StrokeLineJoin.MITER, StrokeLineCap.BUTT, 10, 0, null),
                new CornerRadii(1000), new BorderWidths(5)));
        textField.setBorder(border);

        //头部栏的动画创建
        AnimeProperty animeProperty = new AnimeProperty();
        animeProperty.addKeyFrames(0,0D);
        animeProperty.addKeyFrames(100,1D);
        animeProperty.setDuration(100);
        AnimeJava animeJava = new AnimeJava(animeProperty);

        final boolean[] animeFlag = {false};
        animeJava.update(new AnimeRender() {
            @Override
            public boolean run(Double timeTo, Map<String, PositionVarModel> animeInfo, List<Double> data) {
                if(data.get(0) != null){
                    Parent parent = textField.getParent();
                    textField.setPadding( new Insets(5-data.get(0)*5));
                    Border border1 = new Border(
                            new BorderStroke(Paint.valueOf("#aaf6"),
                                    new BorderStrokeStyle(
                                            StrokeType.OUTSIDE, StrokeLineJoin.MITER, StrokeLineCap.BUTT, 10, 0, null),
                                    new CornerRadii(1000),
                                    new BorderWidths(data.get(0)*5)
                            )
                    );
                    textField.setBorder(border1);
                }
                if(textField.getScene() != null){
                    animeFlag[0] = true;
                }
                if(animeFlag[0]){
                    return textField.getScene() != null;
                }
                return true;
            }
        });
        textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                if (observable.getValue()){
                    animeJava.play();
                }else {
                    animeJava.playFlashback();
                }
            }
        });
        stage.getScene().getRoot().addEventHandler(MouseEvent.ANY , event -> {
            if (event.getEventType()== MouseEvent.MOUSE_CLICKED && event.getPickResult().getIntersectedNode() != textField ) {
                event.getPickResult().getIntersectedNode().requestFocus();
            }
        });
        return  textField;
    }


    /**
     * 右击菜单初始化
     */
    private void popupInit(){
        Scene scene = menu.getScene();
        VBox hBox = new VBox();
        hBox.setAlignment(Pos.CENTER);
        hBox.setStyle("-fx-background-color: #141421 ; -fx-background-radius: 15px ; -fx-border-color: #504c4c ; -fx-border-radius: 15px");
        hBox.setEffect(newBorderBlur());
        hBox.setMinWidth(100);

        menu.focusedProperty().addListener(new ChangeListener<Boolean>() {
            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                System.out.println(observable);
                if(observable.getValue() == false){
                    menuHide();
                }
            }
        });

        scene.setRoot(hBox);
    }

    /**
     * 创建右击菜单
     * @param window
     * @param x
     * @param y
     * @return
     */
    private Pane menuShow(Window window , double x , double y){
        stage.setFocused(false);
        VBox root = (VBox) menu.getScene().getRoot();
        root.getChildren().remove(0,root.getChildren().size());
        menu.show(window , x, y);
        menu.requestFocus();
        return root;
    }

    /**
     * 添加右击的按钮
     * @param pane
     * @param text
     * @return
     */
    private Button addMenuButton(Pane pane , String text){
        Button button = new Button(text);
        button.setPadding(new Insets(5,10,5,10));
        pane.getChildren().add(button);
        VBox vBox = (VBox) pane;
        vBox.setMargin(button,new Insets(3,0,3,0));
        button.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                menuHide();
            }
        });
        return button;
    }

    /**
     * 隐藏右击菜单
     */
    private void menuHide(){
        menu.hide();
    }

    private interface Position{
        void run(AnchorPane position);
    }
    private interface CanvasEvent{
        void event(String data);
    }
    private class CanvasEventBean{
        private CanvasEvent event ;
        public CanvasEventBean() {

        }

        public void execute(Double... data) {
            if(event != null){
                DecimalFormat df = new DecimalFormat("0.00");
                df.setRoundingMode(RoundingMode.HALF_UP);
                String returnData = "";
                for (int i = 0; i < data.length; i++) {
                    returnData += df.format(data[i]/250);
                    if(i <= data.length-2){
                        returnData += ",";
                    }
                }
                event.event(returnData);
            }

        }

        private void addEvent(CanvasEvent event){
            this.event = event;
        }
    }

    /**
     * 动画节点视图
     */
    private class AnimeNodeView{
        AnchorPane anchorPane;
        public AnimeNodeView() {
            this.anchorPane = new AnchorPane();
            anchorPane.setMinHeight(20);
            anchorPane.setMinWidth(250);
            anchorPane.setMaxWidth(250);
        }
        public AnchorPane getNode(){
            return this.anchorPane;
        }

        public void play(Double... data){
            anchorPane.getChildren().clear();

            Node point = createPoint();
            anchorPane.getChildren().add(point);
            AnimeProperty animeProperty = new AnimeProperty();
            animeProperty.setDuration(1200);        //总共耗时 ok
//            animeProperty.setAutoplay(true);
            animeProperty.addKeyFrames(0D,0D);
            animeProperty.addKeyFrames(1D,250D);
            animeProperty.setEasing(new EasingData(data[0], data[1], data[2], data[3]));
            AnimeJava animeJava = new AnimeJava(animeProperty);

            final boolean[] animeFlag = {false};
            animeJava.update(new AnimeRender() {
                @Override
                public boolean run(Double timeTo, Map<String, PositionVarModel> animeInfo, List<Double> data) {
                    if(data.get(0) != null){
                        Platform.runLater(()->{
                            point.setLayoutX(data.get(0));
                        });

                    }
                    if(point.getScene() != null){
                        animeFlag[0] = true;
                    }
                    if(animeFlag[0]){
                        return point.getScene() != null;
                    }
                    return true;
                }
            });
            animeJava.play();

        }
        private Node createPoint(){
            AnchorPane anchorPane = new AnchorPane();
            anchorPane.setStyle("-fx-background-color: rgb(100,76,255) ; -fx-background-radius: 0px");
            anchorPane.setMinWidth(20);
            anchorPane.setMaxWidth(20);
            anchorPane.setMinHeight(20);
            anchorPane.setMaxHeight(20);
            anchorPane.setLayoutY(2);
            anchorPane.setTranslateX(-10);

            return anchorPane;
        }

    }

}
